package com.cloudkinto.service.fbaaaaaa.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.utils.OrderCodeUtil;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.controller.fbaaaaaa.vo.TailTrucksAddReq;
import com.cloudkinto.controller.fbaaaaaa.vo.TailTrucksUpdateStatusReq;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.fbaaaaaa.TailTrucksService;
import com.cloudkinto.service.fbaaaaaa.vo.TailTrucksDetailListRes;
import com.cloudkinto.service.fbaaaaaa.vo.TailTrucksOrderInfo;
import com.cloudkinto.service.fbaaaaaa.vo.TailTrucksPageRes;
import com.cloudkinto.service.fbaorderoutput.FbaOrderOutputService;
import com.cloudkinto.service.firstvesselorder.FirstVesselOrderService;
import com.cloudkinto.service.storage.FbaStorageService;
import com.cloudkinto.service.storage.StorageService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author ding
 * @since 2020-11-24
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class TailTrucksServiceImpl extends ServiceImpl<TailTrucksDao, TailTrucksDo> implements TailTrucksService {
    @Autowired
    private TailTrucksDao dao;
    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private FbaOrderOutputService fbaOrderOutputService;
    @Autowired
    private  FbaOrderOutputDao fbaOrderOutputDao;
    @Autowired
    private FirstVesselOrderPackageDao firstVesselOrderPackageDao;
    @Autowired
    private FirstVesselOrderProductDao firstVesselOrderProductDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private FirstVesselOrderService firstVesselOrderService;
    @Autowired
    private TailTrucksDetailDao tailTrucksDetailDao;

    @Autowired
    private FbaStorageDao fbaStorageDao;
    @Autowired
    private StorageService storageService;
    @Autowired
    private FbaStorageService fbaStorageService;
    @Autowired
    private TrucksTemplateDao trucksTemplateDao;

    @Autowired
    private TailTrucksDetailDao trucksDetailDao;
    @Autowired
    private FbaOrderOutputPackageDao orderOutputPackageDao;
    @Autowired
    private FbaOrderOutputProductDao orderOutputProductDao;
    @Autowired
    private CompanyDao companyDao;


    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }

    @Override
    public Object add(TailTrucksAddReq req, Long userId) {
        TailTrucksDo entityDo = new TailTrucksDo();
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setStatus(1);
        entityDo.setTrucksId(req.getTrucksTempId());
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        dao.insert(entityDo);
        String tailTrucksNumber = OrderCodeUtil.getTailTrucksNumber(entityDo.getId());
        entityDo.setTrucksNumber(tailTrucksNumber);
        dao.updateById(entityDo);
        FbaOrderOutputDo fbaOrderOutputDo = fbaOrderOutputDao.selectById(req.getFbaOrderId());
        fbaOrderOutputDo.setIsTrucks(SysConstant.DELETE_FLAG_TRUE);
        TailTrucksDetailDo detailDo = new TailTrucksDetailDo();
        detailDo.setType(2);
        detailDo.setTrucksId(entityDo.getId());
        detailDo.setOrderId(req.getFbaOrderId());
        detailDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        trucksDetailDao.insert(detailDo);
        return null;
    }

    @Override
    public void jointFbaTrucks(Long orderId, Long userId) {
        List<Long> ids = new ArrayList<>();
        ids.add(orderId);
        //获取所有订单的信息
        TailTrucksOrderInfo orderInfo = getOrderInfo(ids);
        LambdaQueryWrapper<TailTrucksDo> tailListWrapper = new LambdaQueryWrapper<>();
        tailListWrapper.eq(TailTrucksDo::getStorageId, orderInfo.getStorageId())
                .eq(TailTrucksDo::getFbaStorageId, orderInfo.getFbaStorageId())
                .eq(TailTrucksDo::getStatus, DicBusinessItemConstant.tailtruckInCreateState);
        int integer = dao.selectCount(tailListWrapper);
        if (integer > 0) {
            List<TailTrucksDo> trucksDoList = dao.selectList(tailListWrapper);
            double maxRate = 0;
            TailTrucksDo tailTrucksDoTemp = null;
            for (TailTrucksDo tailTrucksDo : trucksDoList) {
                TrucksTemplateDo trucksTemplateDo = trucksTemplateDao.selectById(tailTrucksDo.getTrucksId());
                double bothMax = 0;
                double volume = orderInfo.getTotalVolume() / trucksTemplateDo.getVolume();
                double weight = orderInfo.getTotalWeight() / trucksTemplateDo.getWeight();
                bothMax = weight > volume ? weight : volume;
                if (maxRate < bothMax) {
                    maxRate = bothMax;
                    tailTrucksDoTemp = tailTrucksDo;
                }
            }
            if (tailTrucksDoTemp == null) {
                for (TailTrucksDo tailTrucksDo : trucksDoList) {
                    TrucksTemplateDo trucksTemplateDo = trucksTemplateDao.selectById(tailTrucksDo);
                    LambdaQueryWrapper<TrucksTemplateDo> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TrucksTemplateDo::getStorageId, orderInfo.getStorageId());
                    wrapper.gt(TrucksTemplateDo::getVolume, trucksTemplateDo.getVolume());
                    wrapper.gt(TrucksTemplateDo::getWeight, trucksTemplateDo.getWeight());
                    wrapper.orderByAsc(TrucksTemplateDo::getVolume);
                    List<TrucksTemplateDo> trucksTemplateDos = trucksTemplateDao.selectList(wrapper);
                    if (trucksTemplateDos == null || trucksTemplateDos.size() < 1) continue;
                    trucksTemplateDo = trucksTemplateDos.get(0);
                    double bothMax = 0;
                    double volume = orderInfo.getTotalVolume() / trucksTemplateDo.getVolume();
                    double weight = orderInfo.getTotalWeight() / trucksTemplateDo.getWeight();
                    bothMax = weight > volume ? weight : volume;
                    if (maxRate < bothMax) {
                        maxRate = bothMax;
                        tailTrucksDoTemp = tailTrucksDo;
                    }
                }
            }
            if (tailTrucksDoTemp == null) return;
            tailTrucksDoTemp.setProductCount(tailTrucksDoTemp.getProductCount() + orderInfo.getProductCount());
            tailTrucksDoTemp.setPackageCount(tailTrucksDoTemp.getPackageCount() + orderInfo.getPackageCount());
            tailTrucksDoTemp.setTotalVolume(tailTrucksDoTemp.getTotalVolume() + orderInfo.getTotalVolume());
            tailTrucksDoTemp.setTotalWeight(tailTrucksDoTemp.getTotalWeight() + orderInfo.getTotalWeight());
            updateById(tailTrucksDoTemp);
            //插入从表信息
            handlerInsertTailTrucksDetail(orderId, tailTrucksDoTemp, 2);
            return;
        }
        LambdaQueryWrapper<TrucksTemplateDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TrucksTemplateDo::getStorageId, orderInfo.getStorageId());
        List<TrucksTemplateDo> trucksTemplateDos = trucksTemplateDao.selectList(wrapper);
        if (CollectionUtils.isEmpty(trucksTemplateDos)) throw new BizExceptionI18("no.trunk.templet");
        List<TrucksTemplateDo> trucksTemplateDoList = trucksTemplateDos.stream().sorted(Comparator.comparing(TrucksTemplateDo::getVolume)).sorted(Comparator.comparing(TrucksTemplateDo::getWeight)).collect(Collectors.toList());

        Long templateId = null;
        for (int i = 0; i < trucksTemplateDoList.size(); i++) {
            if ((orderInfo.getTotalVolume() <= trucksTemplateDoList.get(i).getVolume() && orderInfo.getTotalWeight() <= trucksTemplateDoList.get(i).getWeight()) || i == trucksTemplateDoList.size() - 1) {
                templateId = trucksTemplateDoList.get(i).getId();
                break;
            }
        }
        //插入约车主表信息
        TailTrucksDo tailTrucksDo = handlerInsertTailTrucksDo(orderInfo, templateId, userId);

        //插入从表信息
        handlerInsertTailTrucksDetail(orderId, tailTrucksDo, 2);

    }

    private TailTrucksOrderInfo getOrderInfo(List<Long> ids) {
        List<FbaOrderOutputDo> fbaOrderOutputDos = fbaOrderOutputDao.selectBatchIds(ids);
        int packageCount = 0;
        int productCount = 0;
        double totalVolume = 0;
        double totalWeight = 0;
        Set<Long> companySet = new HashSet<>();
        Set<String> poSet = new HashSet<>();
        for (FbaOrderOutputDo fbaOrderOutputDo : fbaOrderOutputDos) {
            LambdaQueryWrapper<FbaOrderOutputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            packageDoLambdaQueryWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, fbaOrderOutputDo.getId());
            List<FbaOrderOutputPackageDo> packageDoList = orderOutputPackageDao.selectList(packageDoLambdaQueryWrapper);
            companySet.add(fbaOrderOutputDo.getCompanyId());
            if (!CollectionUtils.isEmpty(packageDoList)) {
                for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                    if (StringUtils.isNotBlank(packageDo.getPoNumber())) {
                        poSet.add(packageDo.getPoNumber());
                    }
                    packageCount += packageDo.getCount();
                    totalWeight += packageDo.getWeight() * packageDo.getCount();
                    totalVolume += packageDo.getCount() * packageDo.getLength() * packageDo.getHeight() * packageDo.getWidth() / 1000000;

                    LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                    List<FbaOrderOutputProductDo> orderOutputProductDoList = orderOutputProductDao.selectList(productDoLambdaQueryWrapper);
                    if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
                        for (FbaOrderOutputProductDo productDo : orderOutputProductDoList) {
                            productCount += productDo.getCount() * packageDo.getCount();
                        }
                    }
                }
            }
        }
        TailTrucksOrderInfo tailTrucksOrderInfo = new TailTrucksOrderInfo();
        tailTrucksOrderInfo.setCompanySet(companySet);
        tailTrucksOrderInfo.setPackageCount(packageCount);
        tailTrucksOrderInfo.setPoSet(poSet);
        tailTrucksOrderInfo.setProductCount(productCount);
        tailTrucksOrderInfo.setTotalVolume(totalVolume);
        tailTrucksOrderInfo.setTotalWeight(totalWeight);
        tailTrucksOrderInfo.setStorageId(fbaOrderOutputDos.get(0).getStorageId());
        tailTrucksOrderInfo.setFbaStorageId(fbaOrderOutputDos.get(0).getFbaStorageId());

        return tailTrucksOrderInfo;
    }

    private void handlerInsertTailTrucksDetail(Long id, TailTrucksDo tailTrucksDo, Integer type) {
//        for (Long id : ids) {
//            if (type == 1) {
//                FirstVesselOrderDo firstVesselOrderDo = firstVesselOrderService.getBaseMapper().selectById(id);
//                firstVesselOrderDo.setIsContainer(SysConstant.DELETE_FLAG_TRUE);
//                firstVesselOrderService.getBaseMapper().updateById(firstVesselOrderDo);
//            } else if (type == 2) {
        FbaOrderOutputDo fbaOrderOutputDo = fbaOrderOutputDao.selectById(id);
        fbaOrderOutputDo.setIsTrucks(SysConstant.DELETE_FLAG_TRUE);
        fbaOrderOutputDao.updateById(fbaOrderOutputDo);
//            }
        TailTrucksDetailDo detailDo = new TailTrucksDetailDo();
        detailDo.setType(type);
        detailDo.setTrucksId(tailTrucksDo.getId());
        detailDo.setOrderId(id);
        detailDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        trucksDetailDao.insert(detailDo);
//        }

    }

    private TailTrucksDo handlerInsertTailTrucksDo(TailTrucksOrderInfo orderInfo, Long templateId, Long userId) {
        TailTrucksDo tailTrucksDo = new TailTrucksDo();
        tailTrucksDo.setProductCount(orderInfo.getProductCount());
        tailTrucksDo.setPackageCount(orderInfo.getPackageCount());
        tailTrucksDo.setTotalVolume(orderInfo.getTotalVolume());
        tailTrucksDo.setTotalWeight(orderInfo.getTotalWeight());
        tailTrucksDo.setTrucksId(templateId);
        tailTrucksDo.setStorageId(orderInfo.getStorageId());
        tailTrucksDo.setFbaStorageId(orderInfo.getFbaStorageId());
        tailTrucksDo.setStatus(1);
        tailTrucksDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        tailTrucksDo.setCreateBy(userId);
        tailTrucksDo.setCreateTime(new Date());
        if (!CollectionUtils.isEmpty(orderInfo.getCompanySet())) {
            List<Long> companyIdList = new ArrayList<>(orderInfo.getCompanySet());
            StringBuilder stringBuilder = new StringBuilder("");
            for (int i = 0; i < companyIdList.size(); i++) {
                CompanyDo companyDo = companyDao.selectById(companyIdList.get(i));
                if (companyDo == null) continue;
                if (i >= companyIdList.size() - 1) {
                    stringBuilder.append(companyDo.getCompanyCode());
                } else {
                    stringBuilder.append(companyDo.getCompanyCode() + ",");
                }
            }
            tailTrucksDo.setTrucksCompanyCode(stringBuilder.toString());
        }
        if (!CollectionUtils.isEmpty(orderInfo.getPoSet())) {
            List<String> poList = new ArrayList<>(orderInfo.getPoSet());
            StringBuilder stringBuilder = new StringBuilder("");
            for (int i = 0; i < poList.size(); i++) {
                if (i >= poList.size() - 1) {
                    stringBuilder.append(poList.get(i));
                } else {
                    stringBuilder.append(poList.get(i) + ",");
                }
            }
            tailTrucksDo.setPoNumberMuti(stringBuilder.toString());
        }
        dao.insert(tailTrucksDo);
        String tailTrucksNumber = OrderCodeUtil.getTailTrucksNumber(tailTrucksDo.getId());
        tailTrucksDo.setTrucksNumber(tailTrucksNumber);
        dao.updateById(tailTrucksDo);

        return tailTrucksDo;
    }


    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(TailTrucksDo entityDo, Long userId) {
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(TailTrucksDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }

    @Override
    public Object update(Object req, Long userId) {
        /*TailTrucksDo entityDo = dao.selectById(req.getId());
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);
        return handlerUpdateAfter(entityDo);*/
        return null;
    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(TailTrucksDo entityDo, Long userId) {
        entityDo.setUpdateBy(userId);
        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(TailTrucksDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        TailTrucksDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(TailTrucksDo entityDo, Long userId) {
        entityDo.setDeleteBy(userId);
        entityDo.setDeleteTime(new Date());
    }

/*    @Override
    public Object detail(Long id) {
        TailTrucksDo entityDo = dao.selectById(id);
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(res);
    }*/

    @Override
    public List<TailTrucksDetailListRes> detail(Long id) {
        List<TailTrucksDetailListRes> resList = new ArrayList<>();

        LambdaQueryWrapper<TailTrucksDetailDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TailTrucksDetailDo::getTrucksId, id);
        List<TailTrucksDetailDo> tailTrucksDetailDos = tailTrucksDetailDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
            for (TailTrucksDetailDo tailTrucksDetailDo : tailTrucksDetailDos) {
                TailTrucksDetailListRes res = new TailTrucksDetailListRes();
                if (tailTrucksDetailDo.getType() == 1) {
                    res.setType(1);
                    FirstVesselOrderDo firstVesselOrderDo = firstVesselOrderService.getBaseMapper().selectById(tailTrucksDetailDo.getOrderId());
                    if (firstVesselOrderDo == null) continue;
                    res.setId(firstVesselOrderDo.getId());
                    res.setOrderNumber(firstVesselOrderDo.getOrderNumber());
                    CompanyDo companyDo = companyDao.selectById(firstVesselOrderDo.getCompanyId());
                    if (companyDo != null) {
                        res.setCompanyCode(companyDo.getCompanyCode());
                    }
                    FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(firstVesselOrderDo.getFbaStorageId());
                    if (fbaStorageDo != null) {
                        res.setFbaStorage(fbaStorageDo.getFbaCode());
                    }
                    DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(firstVesselOrderDo.getStatus());
                    if (businessItemDo != null) {
                        res.setStatus(businessItemDo.getDicItemValue());
                    }

                    LambdaQueryWrapper<FirstVesselOrderPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    packageDoLambdaQueryWrapper.eq(FirstVesselOrderPackageDo::getOrderId, firstVesselOrderDo.getId());
                    List<FirstVesselOrderPackageDo> packageDoList = firstVesselOrderPackageDao.selectList(packageDoLambdaQueryWrapper);

                    int packageCount = packageDoList.stream().mapToInt(FirstVesselOrderPackageDo::getCount).sum();
                    double totalWeight = 0;
                    double totalVolume = 0;
                    int productCount = 0;

                    res.setPackageCount(packageCount);
                    if (!CollectionUtils.isEmpty(packageDoList)) {
                        for (FirstVesselOrderPackageDo packageDo : packageDoList) {
                            totalVolume += packageDo.getHeight() * packageDo.getLength() * packageDo.getWidth() * packageDo.getCount();
                            totalWeight += packageDo.getCount() * packageDo.getWeight();
                            LambdaQueryWrapper<FirstVesselOrderProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                            productDoLambdaQueryWrapper.eq(FirstVesselOrderProductDo::getPackageId, packageDo.getId());
                            List<FirstVesselOrderProductDo> firstVesselOrderProductDos = firstVesselOrderProductDao.selectList(productDoLambdaQueryWrapper);
                            if (!CollectionUtils.isEmpty(firstVesselOrderProductDos)) {
                                productCount += firstVesselOrderProductDos.stream().mapToInt(FirstVesselOrderProductDo::getCount).sum() * packageDo.getCount();
                            }
                        }
                    }
                    res.setWeight(totalWeight);
                    res.setVolume(numberFormat(totalVolume));
                    res.setProductCount(productCount);

                    resList.add(res);
                } else if (tailTrucksDetailDo.getType() == 2) {
                    res.setType(2);
                    FbaOrderOutputDo orderOutputDo = fbaOrderOutputService.getBaseMapper().selectById(tailTrucksDetailDo.getOrderId());
                    if (orderOutputDo == null) continue;
                    res.setId(orderOutputDo.getId());
                    res.setOrderNumber(orderOutputDo.getFbaOrderOutputNumber());

                    Set<String> poSet = new HashSet<>();
                    LambdaQueryWrapper<FbaOrderOutputPackageDo> packageWrapper = new LambdaQueryWrapper<>();
                    packageWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> fbaOrderOutputPackageDos = orderOutputPackageDao.selectList(packageWrapper);
                    if (!CollectionUtils.isEmpty(fbaOrderOutputPackageDos)) {
                        for (FbaOrderOutputPackageDo packageDo : fbaOrderOutputPackageDos) {
                            poSet.add(packageDo.getPoNumber());
                        }
                    }
                    if (!CollectionUtils.isEmpty(poSet)) {
                        List<String> poList = new ArrayList<>(poSet);
                        StringBuilder stringBuilder = new StringBuilder("");
                        for (int i = 0; i < poList.size(); i++) {
                            if (i >= poList.size() - 1) {
                                stringBuilder.append(poList.get(i));
                            } else {
                                stringBuilder.append(poList.get(i) + ",");
                            }
                        }
                        res.setPoNumber(stringBuilder.toString());
                    }


                    CompanyDo companyDo = companyDao.selectById(orderOutputDo.getCompanyId());
                    if (companyDo != null) {
                        res.setCompanyCode(companyDo.getCompanyCode());
                    }
                    FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                    if (fbaStorageDo != null) {
                        res.setFbaStorage(fbaStorageDo.getFbaCode());
                    }
                    StorageDo storageDo = storageService.getBaseMapper().selectById(orderOutputDo.getStorageId());
                    if (storageDo != null) {
                        res.setStorage(storageDo.getStorageName());
                    }
                    DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
                    if (businessItemDo != null) {
                        res.setStatus(businessItemDo.getDicItemValue());
                    }
                    LambdaQueryWrapper<FbaOrderOutputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    packageDoLambdaQueryWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageDoList = orderOutputPackageDao.selectList(packageDoLambdaQueryWrapper);

                    int packageCount = packageDoList.stream().mapToInt(FbaOrderOutputPackageDo::getCount).sum();
                    double totalWeight = 0;
                    double totalVolume = 0;
                    int productCount = 0;

                    res.setPackageCount(packageCount);

                    if (!CollectionUtils.isEmpty(packageDoList)) {
                        for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                            totalVolume += packageDo.getHeight() * packageDo.getLength() * packageDo.getWidth() * packageDo.getCount() / 1000000;
                            totalWeight += packageDo.getCount() * packageDo.getWeight();
                            LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                            productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                            List<FbaOrderOutputProductDo> orderOutputProductDoList = orderOutputProductDao.selectList(productDoLambdaQueryWrapper);
                            if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
                                productCount += orderOutputProductDoList.stream().mapToInt(FbaOrderOutputProductDo::getCount).sum() * packageDo.getCount();
                            }
                        }
                    }
                    res.setWeight(numberFormat(totalWeight));
                    res.setVolume(numberFormat(totalVolume));
                    res.setProductCount(productCount);

                    resList.add(res);
                }
            }
        }
        //编辑拼柜的po号
        executor.execute(() -> {
            if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
                updatePoNumberHandler(tailTrucksDetailDos.get(0).getTrucksId());
            }
        });
        return resList;
    }



    public void updatePoNumberHandler(Long id) {
        LambdaQueryWrapper<TailTrucksDetailDo> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.eq(TailTrucksDetailDo::getTrucksId, id);
        List<TailTrucksDetailDo> tailTrucksDetailDos = tailTrucksDetailDao.selectList(detailWrapper);
        Set<Long> companyIds = new HashSet<>();
        Set<String> poSet = new HashSet<>();
        if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
            for (TailTrucksDetailDo tailTrucksDetailDo : tailTrucksDetailDos) {
                if (tailTrucksDetailDo.getType() == 1) {
                    FirstVesselOrderDo firstVesselOrderDo = firstVesselOrderService.getBaseMapper().selectById(tailTrucksDetailDo.getOrderId());
                    companyIds.add(firstVesselOrderDo.getCompanyId());
                    LambdaQueryWrapper<FirstVesselOrderPackageDo> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(FirstVesselOrderPackageDo::getOrderId, firstVesselOrderDo.getId());
                    List<FirstVesselOrderPackageDo> firstVesselOrderPackageDos = firstVesselOrderPackageDao.selectList(wrapper);
                    if (!CollectionUtils.isEmpty(firstVesselOrderPackageDos)) {
                        for (FirstVesselOrderPackageDo firstVesselOrderPackageDo : firstVesselOrderPackageDos) {
                            poSet.add(firstVesselOrderPackageDo.getPoNumber());
                        }
                    }
                } else if (tailTrucksDetailDo.getType() == 2) {
                    FbaOrderOutputDo orderOutputDo = fbaOrderOutputService.getBaseMapper().selectById(tailTrucksDetailDo.getOrderId());
                    companyIds.add(orderOutputDo.getCompanyId());
                    LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> fbaOrderOutputPackageDos = orderOutputPackageDao.selectList(wrapper);
                    if (!CollectionUtils.isEmpty(fbaOrderOutputPackageDos)) {
                        for (FbaOrderOutputPackageDo fbaOrderOutputPackageDo : fbaOrderOutputPackageDos) {
                            poSet.add(fbaOrderOutputPackageDo.getPoNumber());
                        }
                    }
                }
            }
        }


        TailTrucksDo tailTrucksDo = this.baseMapper.selectById(id);
        if (!CollectionUtils.isEmpty(companyIds)) {
            List<Long> companyIdList = new ArrayList<>(companyIds);
            StringBuilder stringBuilder = new StringBuilder("");
            for (int i = 0; i < companyIdList.size(); i++) {
                CompanyDo companyDo = companyDao.selectById(companyIdList.get(i));
                if (companyDo == null) continue;
                if (i >= companyIdList.size() - 1) {
                    stringBuilder.append(companyDo.getCompanyCode());
                } else {
                    stringBuilder.append(companyDo.getCompanyCode() + ",");
                }
            }
            tailTrucksDo.setTrucksCompanyCode(stringBuilder.toString());
        }
        if (!CollectionUtils.isEmpty(poSet)) {
            List<String> poList = new ArrayList<>(poSet);
            StringBuilder stringBuilder = new StringBuilder("");
            for (int i = 0; i < poList.size(); i++) {
                if (i >= poList.size() - 1) {
                    stringBuilder.append(poList.get(i));
                } else {
                    stringBuilder.append(poList.get(i) + ",");
                }
            }
            tailTrucksDo.setPoNumberMuti(stringBuilder.toString());
        }
        this.baseMapper.updateById(tailTrucksDo);
    }
    //查询明细之后要执行的业务定制处理
    private Object handlerDetailAfter(Object res) {
        return res;
    }

    private double numberFormat(double f) {
        BigDecimal b = new BigDecimal(f);
        return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    @Override
    public SingleResult pageInit() {
        return SingleResult.success("");
    }

    @Override
    public List<TailTrucksPageRes> getList(Map<String, String> map) {
        QueryWrapper<TailTrucksDo> wrapper = queryBuild(map);
        List<TailTrucksDo> list = this.list(wrapper);
        List<TailTrucksPageRes> result = handlerListAfter(list);
        return result;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<TailTrucksDo> wrapper = queryBuild(map);
        IPage<TailTrucksDo> page = pageInit(map);
        page = this.page(page, wrapper);
        List<TailTrucksPageRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }

    @Override
    public void updateStatus(TailTrucksUpdateStatusReq req) {
        TailTrucksDo tailTrucksDo = this.baseMapper.selectById(req.getId());
        tailTrucksDo.setStatus(4);
        this.baseMapper.updateById(tailTrucksDo);
        handlerOrderStatus(req);
    }
    private void handlerOrderStatus(TailTrucksUpdateStatusReq req) {
        LambdaQueryWrapper<TailTrucksDetailDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TailTrucksDetailDo::getTrucksId, req.getId())
                .eq(TailTrucksDetailDo::getType, 2);
        List<TailTrucksDetailDo> tailTrucksDetailDos = tailTrucksDetailDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
            List<FbaOrderOutputDo> ordersToUpdate = new ArrayList<>();
            for (TailTrucksDetailDo tailTrucksDetailDo : tailTrucksDetailDos) {
                FbaOrderOutputDo fbaOrderOutputDo = fbaOrderOutputService.getBaseMapper().selectById(tailTrucksDetailDo.getOrderId());
                if (fbaOrderOutputDo != null) {
                    fbaOrderOutputDo.setStatus(DicBusinessItemConstant.fbaOrderSignStatus);
                    ordersToUpdate.add(fbaOrderOutputDo);
                }
            }
            updateOrderStatusBatch(ordersToUpdate);
        }
    }

    private void updateOrderStatusBatch(List<FbaOrderOutputDo> orders) {
        for (FbaOrderOutputDo order : orders) {
            order.setStatus(DicBusinessItemConstant.fbaOrderSignStatus);
        }
        fbaOrderOutputDao.updateBatchById(orders);
    }

    //查询分页列表之后对列表数据的处理
  /*  private List<Object> handlerListAfter(List<TailTrucksDo> list) {
        List<Object> result = new ArrayList<>();
        return result;
    }*/

    //查询分页列表之后对列表数据的处理
    private List<TailTrucksPageRes> handlerListAfter(List<TailTrucksDo> list) {
        List<TailTrucksPageRes> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(tailTrucksDo -> {
                TailTrucksPageRes res = new TailTrucksPageRes();
                BeanUtils.copyProperties(tailTrucksDo, res);
                TrucksTemplateDo trucksTemplateDo = trucksTemplateDao.selectById(tailTrucksDo.getTrucksId());
                if (trucksTemplateDo != null) {
                    res.setTrucks(trucksTemplateDo.getTrucksCode());
                    res.setTruckVolume(trucksTemplateDo.getVolume());
                    res.setTruckWeight(trucksTemplateDo.getWeight());
                }
                res.setStatusId(tailTrucksDo.getStatus());
                res.setStatus(getStatusStr(tailTrucksDo.getStatus()));
                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(tailTrucksDo.getFbaStorageId());
                if (fbaStorageDo != null) {
                    res.setFbaStorage(fbaStorageDo.getFbaCode());
                }
                StorageDo storageDo = storageService.getBaseMapper().selectById(tailTrucksDo.getStorageId());
                if (storageDo != null) {
                    res.setStorage(storageDo.getCode());
                }
                List<TailTrucksDetailListRes> detail = detail(tailTrucksDo.getId());
                res.setItems(detail);
                result.add(res);
            });
        }
        return result;
    }

    private String getStatusStr(Integer status) {
        if (status == 1) {
            return "待确定";
        } else if (status == 2) {
            return "待约车";
        } else if (status == 3) {
            return "已约车";
        } else if (status == 4) {
            return "已配送";
        }
        return "";
    }

    private IPage<TailTrucksDo> pageInit(Map<String, String> map) {
        IPage<TailTrucksDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<TailTrucksDo> queryBuild(Map<String, String> map) {
        QueryWrapper<TailTrucksDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.or(tailTrucksDoQueryWrapper -> {
                tailTrucksDoQueryWrapper.like("trucks_number", map.get("keyword")).or().
                        like("po_number_muti", map.get("keyword")
                        ).or().like("appointment_code", map.get("keyword")
                        ).or().like("appointment_code2", map.get("keyword")
                        ).or().like("appointment_code3", map.get("keyword"));
            });
        }
        if (StringUtils.isNotBlank(map.get("status"))) {
            wrapper.eq("status", map.get("status"));
        }
        if (StringUtils.isNotBlank(map.get("fbaStorageId"))) {
            wrapper.eq("fba_storage_id", map.get("fbaStorageId"));
        }
        if (StringUtils.isNotBlank(map.get("storageId"))) {
            wrapper.eq("storage_id", map.get("storageId"));
        }
        if (StringUtils.isNotBlank(map.get("truckId"))) {
            wrapper.eq("truck_id", map.get("truckId"));
        }
        if (StringUtils.isNotBlank(map.get("companyCode"))) {
            wrapper.like("trucks_company_code", map.get("companyCode"));
        }
        if (StringUtils.isNotBlank(map.get("startDate"))) {
            wrapper.ge("create_time", map.get("startDate"));
        }
        if (StringUtils.isNotBlank(map.get("endDate"))) {
            wrapper.le("create_time", map.get("endDate"));
        }
        return wrapper.orderByDesc("id");
    }


}
